home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / bash / bash_108 / src_d2.zoo / bash-d2.zoo / libgcc / pipe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-03  |  4.9 KB  |  126 lines

  1. #include <fcntl.h>
  2. #include <stat.h>
  3. #include <types.h>
  4. #include <errno.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. /**
  9.  ** (sjk)++ These routines simulate a eunchs pipe() call using temporary 
  10.  **         files. A linked list of type *_pipe is kept as to allow as 
  11.  **         many open pipes as there are valid file descriptors. The only 
  12.  **         problem is that the pipe is initiallialy opened for writing, 
  13.  **         and all output must be done to the pipe, then call pipeclose(fd);
  14.  **         and it sets up the pipe for reading. After all input is done, 
  15.  **         call pipeclose(fd) again and this will close the pipe and delete
  16.  **         the temporary file that the pipe created.
  17.  **    
  18.  **/
  19.  
  20. struct _pipe { char p_name[40];
  21.            char flag;               /* "r"-->read, "w"-->write */
  22.            int  file_des;
  23.            struct _pipe *next;
  24.              };
  25. static struct _pipe *__pipes = NULL;
  26.  
  27. /*---------------------------------------------------------------------------*/
  28. /* Make a pipe, open the tempory file, set it up for writing, add the pipe   */
  29. /* descriptor to our linked list of pipes, and return.                       */
  30. /*---------------------------------------------------------------------------*/
  31. int pipe(fildes)
  32. int fildes[2];
  33. { int       fd,ifd; 
  34.   char name[40];
  35.   struct _pipe *p;
  36.  
  37.   tmpnam(name);                              /* Make a temporary file name. /*
  38.   
  39.   /*----------------------------------------------*/
  40.   /* Open the pipe for reading and writing.       */
  41.   /*----------------------------------------------*/
  42.   fd = open(name,O_CREAT | O_TRUNC | O_RDWR | O_PIPE, 0644); 
  43.  
  44.   if (fd < 0)
  45.     fprintf(stderr,"fd returns : %d! PIPE failed.\n",fd);
  46.   else 
  47.     { /*------------------------------------------*/
  48.       /* Get a pipe description block and         */
  49.       /* put in the (1)file name,                 */
  50.       /*            (2)file descriptor,           */
  51.       /*            (3)file mode = "w".           */
  52.       /*------------------------------------------*/
  53.       /*-------------------------------------------------------------------*/
  54.       p = (struct _pipe *)malloc(sizeof (struct _pipe)); 
  55.       strcpy(p->p_name,name);           /* fill in name.                   */  
  56.       p->flag = 'w';                    /* initially for write.            */
  57.       p->file_des = fd;                 /* fill in the pipe descriptor.    */
  58.       /*-------------------------------------------------------------------*/
  59.       p->next = __pipes;                /* Link to our list of open pipes. */
  60.       __pipes     = p;
  61.       /*-------------------------------------------------------------------*/ 
  62.       fildes[0] = fildes[1] = fd;       /* we fill in fildes[].            */
  63.     }
  64.   return(fd);                           /* Return the file descriptor.     */
  65. }
  66.  
  67. /*---------------------------------------------------------------------*/
  68. /* close a pipe, if the pipe was open for writing, set it to a read    */
  69. /* read pipe, and lseek to the begining of the pipe. if it was open    */
  70. /* for reading then close the pipe, delete the temporary file, and     */
  71. /* remove the pipe descriptor from the __pipes linked list.            */
  72. /*---------------------------------------------------------------------*/
  73. int
  74. pipeclose(fd)
  75. int fd;
  76. {  struct _pipe *p,*q = NULL;
  77.    int    ifd;
  78.    for (p=__pipes; p; p=p->next)
  79.     { if (fd == p->file_des) 
  80.         if (p->flag == 'r') 
  81.       { int res;
  82.         ifd = __OPEN_INDEX(fd);
  83.             __open_stat[ifd].pipe = 0;            /* So close wont recurse */
  84.         res = close(fd);
  85.         unlink(p->p_name);                     /* Delete it.            */
  86.             del_list(p);                           /* delete from the list. */
  87.             return(res);                               
  88.           }
  89.         else 
  90.         if (p->flag =='w')
  91.           { p->flag = 'r';                         /* now make it read.     */
  92.             lseek(p->file_des,0,SEEK_SET);         /* read from the start.  */
  93.             return(0);
  94.           }
  95.     }
  96.    fprintf(stderr,"attempt to close nonexistant pipe.\n");
  97.    return(-1);
  98. }
  99.  
  100. /*---------------------------------------------------------------------*/
  101. /* delete a pipe descriptor from our list of pipes rooted ar __pipes.  */
  102. /*---------------------------------------------------------------------*/
  103. del_list(p)
  104. struct _pipe *p;
  105. { struct _pipe *q,*r;
  106.   
  107.   if (p == __pipes)                      /* Is it the first element?    */
  108.     { __pipes = p->next; 
  109.       free(p);
  110.       return(0);
  111.     }
  112.   else 
  113.     { r = p->next; q = p;               /* No it is interior.           */
  114.       for (; r; r = r->next)
  115.         { if (r == p)
  116.            { q->next = r->next;              /* pass over it.   */
  117.              free(r);                        /* free its space. */
  118.              return(0);                      /* go home.        */
  119.        }
  120.           q = r;                        /* update trailing pointer.    */
  121.     }
  122.     }
  123.   fprintf(stderr,"Attempt to delete a nonexisting pipe form list (__pipes).");
  124. }
  125.  
  126.